package com.jdd.modules.parkmonthly.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jdd.common.api.vo.Result;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.DateUtil;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.SnowFlakeUtil;
import com.jdd.modules.configcartype.entity.ConfigCarType;
import com.jdd.modules.parkcar.entity.ParkCarMonthly;
import com.jdd.modules.parkcar.entity.ParkSpace;
import com.jdd.modules.parkcar.service.IParkCarMonthlyService;
import com.jdd.modules.parkcar.service.IParkSpaceService;
import com.jdd.modules.parking.entity.ParkCarEnterLog;
import com.jdd.modules.parking.service.IConfigParkInfoService;
import com.jdd.modules.parking.service.IparkCarEnterLogService;
import com.jdd.modules.parkmonthly.entity.MonthlyCarTypeConvert;
import com.jdd.modules.parkmonthly.entity.MonthlyCardInfo;
import com.jdd.modules.parkmonthly.entity.MonthlyPackageInfo;
import com.jdd.modules.parkmonthly.service.IEditMonthlyCardInfoService;
import com.jdd.modules.parkmonthly.service.IMonthlyCarTypeConvertService;
import com.jdd.modules.parkmonthly.service.IMonthlyCardInfoService;
import com.jdd.modules.parkmonthly.service.IMonthlyPackageInfoService;
import com.jdd.modules.sdkidentifyresultpushlog.entity.vo.ParkCarEnterLogSyncV3Vo;
import com.jdd.modules.sdkidentifyresultpushlog.service.ISdkIdentifyResultPushLogV3Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 月卡编辑
 * @Author: qilina
 * @Date: 2022-1-7
 * @Version: V2.0
 */
@Service
@Slf4j
public class EditMonthlyCardInfoServiceImpl implements IEditMonthlyCardInfoService {

    @Resource
    private IMonthlyCarTypeConvertService iMonthlyCarTypeConvertService;
    @Resource
    private IMonthlyPackageInfoService iMonthlyPackageInfoService;
    @Resource
    private IMonthlyCardInfoService iMonthlyCardInfoService;
    @Resource
    private IparkCarEnterLogService iparkCarEnterLogService;
    @Resource
    private IParkCarMonthlyService iParkCarMonthlyService;
    @Resource
    private IParkSpaceService parkSpaceService;
    @Resource
    private IConfigParkInfoService configParkInfoService;
    @Resource
    private ISdkIdentifyResultPushLogV3Service sdkIdentifyResultPushLogV3Service;



    /**
     * 编辑月卡信息  月租编号,月租套餐,通行权限,车位编号,起始截止时间,金额不能改  其他都可以改
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
    @CacheEvict(value = {"monthly:cardAndPackage"}, allEntries = true)
    public Result<MonthlyCardInfo> editMonthlyCard(MonthlyCardInfo monthlyCardInfo) {

        MonthlyCardInfo monthlyCardInfoEntity = iMonthlyCardInfoService.getById(monthlyCardInfo.getId());
        if (monthlyCardInfoEntity == null) {
            return Result.error("未找到对应月卡信息");
        }

        boolean resFlag = true;
        // 删除车牌号,走注销逻辑
        List<String> deletePlateNos = monthlyCardInfo.getDeletePlateNos();
        if (CollectionUtil.isNotEmpty(deletePlateNos)) {
            deletePlateNo(deletePlateNos, monthlyCardInfo);
        }
        MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
        // 新增车牌号
        List<String> addPlateNo = monthlyCardInfo.getAddPlateNos();
        if (CollectionUtil.isNotEmpty(addPlateNo)) {
            QueryWrapper<ParkSpace> parkSpaceQueryWrapper = new QueryWrapper<>();
            parkSpaceQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
            parkSpaceQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
            List<ParkSpace> spaces = parkSpaceService.list(parkSpaceQueryWrapper);
            log.info("编辑页面，查询绑定车位信息---------------------》:{}", spaces);
            // 新增月租车
            List<ParkCarMonthly> list = iMonthlyCardInfoService.getParkCarMonthlyEntity(spaces, addPlateNo, monthlyCardInfoEntity);
            iParkCarMonthlyService.saveBatch(list);
        }
        // 月卡不过期，才会转卡
        if (monthlyCardInfoEntity.getEndTime().after(new DateTime())) {
            log.info("-----------编辑转卡----------");
            dealEditAdd(monthlyCardInfoEntity, monthlyPackageInfo);
        }
        // 1.修改月卡
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        if (null != loginUser) {
            monthlyCardInfoEntity.setUpdateUserId(loginUser.getUsername());
            monthlyCardInfoEntity.setUpdateUserName(loginUser.getRealname());
        }
        monthlyCardInfoEntity.setUpdateTime(new Date());
        monthlyCardInfoEntity.setAddress(monthlyCardInfo.getAddress());
        monthlyCardInfoEntity.setTelephone(monthlyCardInfo.getTelephone());
        monthlyCardInfoEntity.setRemark(monthlyCardInfo.getRemark());
        monthlyCardInfoEntity.setCarOwnerName(monthlyCardInfo.getCarOwnerName());
        monthlyCardInfoEntity.setMonthlyDepartmentId(monthlyCardInfo.getMonthlyDepartmentId());
        monthlyCardInfoEntity.setMonthlyDepartmentName(monthlyCardInfo.getMonthlyDepartmentName());
        resFlag = iMonthlyCardInfoService.updateById(monthlyCardInfoEntity);
        if (!resFlag) {
            return Result.error("修改失败!");
        }

        // 3.新增月卡操作记录
        iMonthlyCardInfoService.getMonthlyCardEditInfo(monthlyCardInfoEntity, JddConstant.StringNumber.STRING_FIVE);
        return Result.ok("修改成功");
    }


    /**
     * 处理编辑时，释放车位后，非过期转卡
     *
     * @param monthlyCardInfo
     * @param monthlyPackageInfo
     */
    private void dealEditAdd(MonthlyCardInfo monthlyCardInfo, MonthlyPackageInfo monthlyPackageInfo) {

        // 查询未被绑定的车位信息
        QueryWrapper<ParkSpace> spaceQueryWrapper = new QueryWrapper<>();
        spaceQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
        spaceQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        spaceQueryWrapper.eq("park_status", 0);
        List<ParkSpace> unUsePace = parkSpaceService.list(spaceQueryWrapper);
        log.info("unUsePace--------------------->:{}", unUsePace);
        if (CollectionUtils.isEmpty(unUsePace)) {
            return;
        }
        // 查询绑定月租车
        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
        parkCarMonthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        List<ParkCarMonthly> parkCarMonthlyList = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        // 获取绑定月租的车牌信息，区域信息
        List<String> plateNos = parkCarMonthlyList.stream().map(ParkCarMonthly::getPlateNo).distinct().collect(Collectors.toList());
        List<String> areaIds = parkCarMonthlyList.stream().map(ParkCarMonthly::getAreaId).distinct().collect(Collectors.toList());
        // 不支持多区域转卡
        log.info("areaIds--------------->:{}", areaIds);
        if (areaIds.size() > 1) {
            return;
        }
        // 查询在场记录
        List<ParkCarEnterLog> enterLogList = iMonthlyCardInfoService.getList(monthlyCardInfo.getParkCode(), plateNos, areaIds);
        log.info("enterLogList--------------------->:{}", enterLogList);
        if (CollectionUtils.isEmpty(enterLogList)) {
            return;
        }
        // 处理编辑在场
        iMonthlyCardInfoService.dealCarLog(enterLogList, unUsePace, monthlyCardInfo, monthlyPackageInfo);
    }


    /**
     * 删除的关联车牌号的的月租车信息
     *
     * @param
     * @return
     */
    public void deletePlateNo(List<String> plateNos, MonthlyCardInfo monthlyCardInfo) {

        // 删除租车信息
        log.info("删除关联车位信息，传入参数--------------------------》:{}", plateNos);
        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        parkCarMonthlyQueryWrapper.in("plate_no", plateNos);
        List<ParkCarMonthly> parkCarMonthlyList = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        List<String> araIds = parkCarMonthlyList.stream().map(ParkCarMonthly::getAreaId).distinct().collect(Collectors.toList());
        // 获取删除的场内车辆月租车入场记录
        List<ParkCarEnterLog> fieldParkCarEnterLog = iMonthlyCardInfoService.getList(monthlyCardInfo.getParkCode(), plateNos, araIds);
        log.info("删除的场内车辆月租车牌号的入场记录为---------:{}", fieldParkCarEnterLog);
        if (CollectionUtil.isNotEmpty(fieldParkCarEnterLog)) {
            MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
            List<ParkCarEnterLog> parkCarEnterLogs = new ArrayList<>();
            List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
            for (ParkCarEnterLog parkCarEnterLog : fieldParkCarEnterLog) {
                // 编辑删除车牌时，临时车不需要转卡新增入场记录 update by qilina
                if ("0".equals(parkCarEnterLog.getCarNature())) {
                    continue;
                }
                // 修改车牌号，删除原有车牌号的车位
                QueryWrapper<ParkSpace> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("monthly_card_id", monthlyCardInfo.getId());
                queryWrapper1.eq("plate_no", parkCarEnterLog.getPlateNo());
                queryWrapper1.eq("park_number", parkCarEnterLog.getParkNumber());
                ParkSpace parkSpace = parkSpaceService.getOne(queryWrapper1);
                parkSpace.setParkStatus("0");
                parkSpace.setPlateNo("");
                parkSpaceService.updateById(parkSpace);
                ParkCarEnterLog newParkCarEnterLog = new ParkCarEnterLog();
                BeanUtils.copyProperties(parkCarEnterLog, newParkCarEnterLog);
                newParkCarEnterLog.setId(SnowFlakeUtil.getId());
                // 判断月租是否过期,过期
                if (monthlyCardInfo.getEndTime().before(new Date()) &&
                        DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).before(monthlyCardInfo.getEndTime())) {
                    newParkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getEndTime()));
                }
                if (new Date().before(monthlyCardInfo.getEndTime())) {
                    newParkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(new Date()));
                }
                newParkCarEnterLog.setCreateTime(new Date());
                newParkCarEnterLog.setCarNature(JddConstant.StringNumber.STRING_ZERO);
                newParkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
                ConfigCarType configCarType = iMonthlyCardInfoService.getCarType(newParkCarEnterLog.getParkCode(), Integer.valueOf(newParkCarEnterLog.getCarTypeNo()));
                if (null != configCarType) {
                    newParkCarEnterLog.setCarTypeName(configCarType.getCarTypeName());
                    newParkCarEnterLog.setCarTypeId(configCarType.getId());
                }
                newParkCarEnterLog.setMonthlyCardId("");
                newParkCarEnterLog.setParkNumber("");
                parkCarEnterLogs.add(newParkCarEnterLog);
                //组装转卡记录
                MonthlyCarTypeConvert monthlyCarTypeConvert = iMonthlyCardInfoService.getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, monthlyPackageInfo);
                monthlyCarTypeConverts.add(monthlyCarTypeConvert);
            }
            // 更新车位，插入入场，转卡
            if(parkCarEnterLogs .size() > 0){
            	iparkCarEnterLogService.saveBatch(parkCarEnterLogs);
            	try {
					for(ParkCarEnterLog parkCarEnterLog : parkCarEnterLogs){
						ParkCarEnterLogSyncV3Vo entity = new ParkCarEnterLogSyncV3Vo();
						entity.setParkCarEnterLogStr(JSON.toJSONString(parkCarEnterLog));
						// 月租车
						if(StringUtils.isNotBlank(parkCarEnterLog.getParkNumber())){
							entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ONE);
							entity.setSourceAreaId(parkCarEnterLog.getAreaId());
						}else{
							// 临时车
							entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ZERO);
						}
                        String url = "";
						sdkIdentifyResultPushLogV3Service.sendMessageV3(entity,url);
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.info("新增月租车上传到云端失败->{}",e);
				}
            }
            iMonthlyCarTypeConvertService.saveBatch(monthlyCarTypeConverts);
        }
        QueryWrapper<ParkCarMonthly> monthlyQueryWrapper = new QueryWrapper<>();
        monthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        monthlyQueryWrapper.in("plate_no", plateNos);
        iParkCarMonthlyService.remove(monthlyQueryWrapper);
    }
}
